home *** CD-ROM | disk | FTP | other *** search
/ MacHack 1994 / MacHack 1994.toast / MacHack™94 / Talks & Papers / Michael D. Crawford↵ / Word Services SDK 1.0.5 / Writeswell Jr. Source / ServiceDialog.c < prev    next >
Text File  |  1993-03-17  |  10KB  |  435 lines

  1. /* ServiceMgr.c
  2.  * Handle the Services menu in Writeswell, Jr.
  3.  * ©1992 Working Software, Inc.
  4.  * This source code is copyrighted.  Permission is granted to use the Word Services
  5.  * portion of the Writeswell Jr. source code in your own programs, but you 
  6.  * may not distribute the Writeswell Jr. word-processor code as a 
  7.  * commercial product.  If you modify the code, please do not call it 
  8.  * Writeswell Jr. (or Writeswell.)  This will ensure that people understand the 
  9.  * program and don’t have to deal with a number of different versions with 
  10.  * who-knows-what going on in the code.
  11.  * 
  12.  * Writeswell Jr. and Writeswell are trademarks of Working Software, Inc.
  13.  * 19 Apr 92 Mike Crawford
  14.  */
  15.  
  16. #include <Aliases.h>
  17. #include <AppleEvents.h>
  18. #include "TestBed.h"
  19. #include "TBConstants.h"
  20. #include "Gripe.h"
  21. #include "Prefs.h"
  22. #include "ServiceMgr.h"
  23. #include "TBGlobals.h"
  24. #include "ServiceDialog.h"
  25. #include "OutlineButton.h"
  26. #include "Key.h"
  27. #include "InitMenu.h"
  28.  
  29. pascal void ServiceListProc( DialogPtr theDialog, short item );
  30. OSErr MakeServiceList( DialogPtr dPtr );
  31. OSErr FillServiceList( ListHandle lHdl );
  32. pascal Boolean RemoveDlogProc( DialogPtr theDialog,
  33.                                 EventRecord *eventPtr,
  34.                                 short *itemPtr );
  35. void HiliteRemoveButton( DialogPtr dPtr, ListHandle lHdl );
  36. void RemoveSelectedServices( ListHandle lHdl );
  37.  
  38. void RemoveServices( void )
  39. {
  40.     DialogPtr    servDlg;
  41.     short        item;
  42.     Str255        textStr;
  43.     short        kind;
  44.     Handle        h;
  45.     Rect        r;
  46.     long        num;
  47.     ListHandle    lHdl;
  48.     OSErr        err;
  49.     
  50.     servDlg = GetNewDialog( rRemoveDialogID, (Ptr)NULL, (WindowPtr)-1 );
  51.     if ( !servDlg )
  52.         return;
  53.     
  54.     /* Set up a user proc to draw the default outline */
  55.  
  56.     GetDItem( servDlg, kRDDefUser, &kind, &h, &r );
  57.     SetDItem( servDlg, kRDDefUser, kind, (Handle)OutlineButton, &r );
  58.  
  59.     /* Set up the user proc to draw the service list */
  60.     GetDItem( servDlg, kRDListUser, &kind, &h, &r );
  61.     SetDItem( servDlg, kRDListUser, kind, (Handle)ServiceListProc, &r );
  62.  
  63.     err = MakeServiceList( servDlg );
  64.     if ( err ){
  65.         Gripe( "\pMakeServiceList failed" );
  66.         return;
  67.     }
  68.  
  69.     lHdl = (ListHandle)GetWRefCon( servDlg );
  70.  
  71.     err = FillServiceList( lHdl );
  72.     if ( err ){
  73.         Gripe( "\pFillServiceList failed" );
  74.         return;    
  75.     }
  76.  
  77.     SetPort( servDlg );
  78.  
  79.     LDoDraw( true, lHdl );
  80.  
  81.     HiliteRemoveButton( servDlg, lHdl );
  82.  
  83.     do {
  84.         ModalDialog( (ProcPtr)RemoveDlogProc, &item );
  85.         
  86.         if ( item == kRDRemove ){
  87.             RemoveSelectedServices( lHdl );
  88.             HiliteRemoveButton( servDlg, lHdl );
  89.         }
  90.  
  91.     } while ( item != kRDDone );
  92.     
  93.     LDispose( lHdl );
  94.  
  95.     DisposDialog( servDlg );
  96.     
  97.     RebuildServiceMenu();
  98.     
  99.     return;
  100. }
  101.  
  102. pascal void ServiceListProc( DialogPtr theDialog, short item )
  103. {
  104.     Handle        itemHdl;
  105.     short        itemKind;
  106.     Rect        itemRect;
  107.     PenState    oldPenState;
  108.     ListHandle    lHdl;
  109.  
  110.     /* Get the user item rectangle */
  111.     GetDItem( theDialog, item, &itemKind, &itemHdl, &itemRect );
  112.  
  113.     /* Draw the frame around the list */
  114.     GetPenState( &oldPenState );
  115.     PenNormal();
  116.         
  117.     FrameRect( &itemRect );
  118.     
  119.     SetPenState( &oldPenState );
  120.     
  121.     /* Update the list itself */
  122.  
  123.     lHdl = (ListHandle)GetWRefCon( (WindowPtr)theDialog );
  124.     
  125.     LUpdate( ( (WindowPeek)theDialog )->port.visRgn, lHdl );
  126.  
  127.     return;
  128. }
  129.  
  130. OSErr MakeServiceList( DialogPtr dPtr )
  131. {
  132.     Handle        itemHdl;
  133.     short        itemKind;
  134.     Rect        itemRect;
  135.     Rect        listRect;
  136.     Rect        dataBounds;
  137.     Point        cellSize;
  138.     ListHandle    lHdl;
  139.  
  140.     /* Get the rect from the dialog user item.
  141.      * The user item exists in the DITL as a placeholder for us to get a rect
  142.      * from, and also to report hits on.
  143.      */
  144.     GetDItem( dPtr, kRDListUser, &itemKind, &itemHdl, &itemRect );
  145.     
  146.     /* Make room for the scroll bar.  This is outside of the rect that is passed to
  147.      * LNew.
  148.      * We use a copy of the rect so we don't change the real one in the dialog
  149.      */
  150.     
  151.     listRect = itemRect;                    /* Structure Assignment */
  152.     listRect.right -= kListScrollBarWidth;
  153.     InsetRect( &listRect, 1, 1 );            /* 1 pixel inside user item to allow outline */
  154.     
  155.     /* Set up the data bounds for a single column list,  with no initial elements */
  156.     SetRect( &dataBounds, 0, 0, 1, 0 );
  157.     
  158.     /* Use the default cell size */
  159.     cellSize.h = 0;
  160.     cellSize.v = 0;
  161.     
  162.     /* make the list */
  163.     lHdl = LNew( &listRect, &dataBounds, cellSize, kListTextProc,
  164.                             (WindowPtr) dPtr, false, false, false, true );
  165.  
  166.     if ( !lHdl || !*lHdl ){
  167.         Gripe( "\pLNew failed" );
  168.         return memFullErr;
  169.     }
  170.  
  171.     SetWRefCon( dPtr, (long)lHdl );
  172.  
  173.     /* Get the filenames for the list, and install them */
  174.     
  175.     return noErr;
  176. }
  177.  
  178. OSErr FillServiceList( ListHandle lHdl )
  179. {
  180.     WWJrPrefsHdl    prefHdl;
  181.     short            i;
  182.     short            servNum;
  183.     StringHandle    menuStrHdl;
  184.     short            curFile;
  185.     MenuHandle        servMenu;
  186.     short            resID;
  187.     Cell            newCell;
  188.  
  189.     prefHdl = GetPrefHandle();
  190.     if ( !prefHdl ){
  191.         Gripe( "\pCannot get preferences handle" );
  192.         return;
  193.     }
  194.  
  195.     curFile = CurResFile();
  196.     UseResFile( gPrefFileRefNum );
  197.  
  198.     servNum = 0;
  199.  
  200.     newCell.h = 0;
  201.  
  202.     for ( i = 0; i < kMaxServices; i++ ){
  203.         if ( (*prefHdl)->serviceType[ i ] != kNoService ){
  204.         
  205.             resID = kServiceBaseID + i;
  206.  
  207.             menuStrHdl = GetString( resID );
  208.             if ( !menuStrHdl ){
  209.                 Gripe( "\pCannot get string resource for service menu" );
  210.                 UseResFile( curFile );
  211.                 return resNotFound;
  212.             }
  213.             
  214.             newCell.v = servNum++;
  215.  
  216.             LAddRow( 1, 32767, lHdl );
  217.  
  218.             HLock( menuStrHdl );
  219.             LSetCell( &( (*menuStrHdl)[1] ), (short)((*menuStrHdl)[0]), newCell, lHdl );
  220.             HUnlock( menuStrHdl );
  221.  
  222.             ReleaseResource( menuStrHdl );            
  223.         }
  224.     }
  225.  
  226.     UseResFile( curFile );
  227.     return noErr;
  228. }
  229.  
  230. pascal Boolean RemoveDlogProc( DialogPtr theDialog,
  231.                                 EventRecord *eventPtr,
  232.                                 short *itemPtr )
  233. {
  234.     Handle h;
  235.     short kind;
  236.     Rect listRect;
  237.     Point localPt;
  238.     ListHandle listHdl;
  239.  
  240.     switch( eventPtr->what ){
  241.         case keyDown:
  242.             switch( eventPtr->message & charCodeMask ){
  243.                 case enterKey:
  244.                 case retKey:
  245.                 case escKey:
  246.                     *itemPtr = kRDDone;        /* Take safe way out.  May not like this */
  247.                     return true;
  248.                     break;
  249.             }
  250.             break;
  251.         case mouseDown:
  252.             /* check if it's in the list.  Have to do this in the Proc so we can
  253.              * look at the event record
  254.              */
  255.  
  256.             GetDItem( theDialog, kRDListUser, &kind, &h, &listRect );
  257.  
  258.             localPt = eventPtr->where;
  259.             GlobalToLocal( &localPt );
  260.  
  261.             if ( PtInRect( localPt, &listRect ) ){
  262.  
  263.                 /* Work around a bug in the List Manager where if there are several
  264.                  * files selected, an unshifted click will not deselect the selected files
  265.                  */
  266.                 
  267.                 listHdl = (ListHandle)GetWRefCon( (WindowPtr)theDialog );
  268.  
  269.                 if ( ! (eventPtr->modifiers & shiftKey) &&
  270.                          !(eventPtr->modifiers & cmdKey) ){
  271.                     
  272.                 
  273.                     if ( PtInRect( localPt, &((*listHdl)->rView) ) ){
  274.                         Cell myCell;
  275.                         
  276.                         /* LDoDraw( false, listhdl ); */
  277.                         
  278.                         myCell.h = 0;
  279.                         myCell.v = 0;
  280.                         
  281.                         while ( LGetSelect( true, &myCell, listHdl ) ){
  282.                             LSetSelect( false, myCell, listHdl );
  283.                         }
  284.                         
  285.                         /* LDoDraw( true, listHdl ); */
  286.                     }
  287.                 }
  288.                 /* We presently don't care if they double-clicked */
  289.                 LClick( localPt, eventPtr->modifiers, listHdl );
  290.                 HiliteRemoveButton( theDialog, listHdl );
  291.             }
  292.             break;
  293.         case updateEvt:
  294.             LUpdate( ( (WindowPeek)theDialog )->port.visRgn,
  295.                 (ListHandle)GetWRefCon( (WindowPtr)theDialog ) );
  296.             break;
  297.     }
  298.  
  299.     return false;
  300. }
  301.  
  302. /* Dim or Hilite Remove button according to whether there is a selection */
  303.  
  304. void HiliteRemoveButton( DialogPtr dPtr, ListHandle lHdl )
  305. {
  306.     Handle itemHdl;
  307.     short itemKind;
  308.     Rect itemRect;
  309.     Cell theCell;
  310.  
  311.     GetDItem( dPtr, kRDRemove, &itemKind, &itemHdl, &itemRect );
  312.     
  313.     theCell.h = 0;
  314.     theCell.v = 0;
  315.     
  316.     if ( LGetSelect( true, &theCell, lHdl ) ){
  317.         HiliteControl( (ControlHandle)itemHdl, 0 );
  318.     } else {
  319.         HiliteControl( (ControlHandle)itemHdl, 255 );
  320.     }
  321.  
  322.     return;
  323. }
  324.  
  325. void RemoveSelectedServices( ListHandle lHdl )
  326. {
  327.     WWJrPrefsHdl    prefHdl;
  328.     short            i;
  329.     short            index;
  330.     short            servCount;
  331.     short            curFile;
  332.     short            resID;
  333.     short            iconResID;
  334.     Cell            nextCell;
  335.     Handle            menuStrHdl;
  336.     Handle            aliasHdl;
  337.     Handle            iconHdl;
  338.     short            itemNo;
  339.  
  340.     prefHdl = GetPrefHandle();
  341.     if ( !prefHdl ){
  342.         Gripe( "\pCannot get preferences handle" );
  343.         return;
  344.     }
  345.  
  346.     curFile = CurResFile();
  347.     UseResFile( gPrefFileRefNum );
  348.  
  349.     nextCell.h = 0;
  350.     nextCell.v = 0;
  351.         
  352.  
  353.     while ( LGetSelect( true, &nextCell, lHdl ) ){
  354.         
  355.         itemNo = nextCell.v + 1;
  356.  
  357.         /* We need to unselect the cell we just got so it won't be gotten repeatedly
  358.          * at the end 
  359.          */
  360.         
  361.         LSetSelect( false, nextCell, lHdl );
  362.  
  363.         index = 0;
  364.         servCount = 0;
  365.         
  366.         do {
  367.         
  368.             if ( (*prefHdl)->serviceType[ index++ ] != kNoService )
  369.                 servCount++;
  370.  
  371.         } while ( servCount < itemNo );
  372.  
  373.         index--;
  374.         
  375.         (*prefHdl)->serviceType[ index ] = kNoService;
  376.         
  377.         resID = kServiceBaseID + index;
  378.         
  379.         /* Remove the resource */
  380.         
  381.         menuStrHdl = GetResource( 'STR ', resID );
  382.         
  383.         if ( !menuStrHdl ){
  384.             Gripe( "\pFailed to get menu string in RemoveSelectedServices" );
  385.             UseResFile( curFile );
  386.             return;
  387.         }
  388.         
  389.         RmveResource( menuStrHdl );
  390.  
  391.         /* 1.1.1 MDC Fix memory leak */
  392.         
  393.         DisposHandle( menuStrHdl );
  394.  
  395.         aliasHdl = GetResource( rAliasType, resID );
  396.         
  397.         if ( !aliasHdl ){
  398.             Gripe( "\pFailed to get alias resource in RemoveSelectedServices" );
  399.             UseResFile( curFile );
  400.             return;
  401.         }
  402.         
  403.         RmveResource( aliasHdl );
  404.  
  405.         /* 1.1.1 MDC Fix memory leak */
  406.         
  407.         DisposHandle( aliasHdl );
  408.  
  409.         /* Remove the icon */
  410.  
  411.         iconResID = kMenuIconBaseID + index;
  412.         
  413.         iconHdl = GetResource( 'SICN', iconResID );
  414.         
  415.         /* It is permissible for there to be no icon resource */
  416.  
  417.         if ( iconHdl ){
  418.             RmveResource( iconHdl );
  419.  
  420.             /* 1.1.1 MDC Fix memory leak */
  421.             
  422.             DisposHandle( iconHdl );
  423.  
  424.         }
  425.  
  426.         LDelRow( 1, nextCell.v, lHdl );            /* Take item out of list */
  427.     }
  428.  
  429.     ChangedResource( prefHdl );
  430.     WriteResource( prefHdl );
  431.  
  432.     UseResFile( curFile );
  433.     return;
  434. }
  435.